﻿
/*
Sample Request
[
  {
     "type": "chat",
     "chatID": 23,
     "content":
         [
             {
                "type": "msg",
                "msg": "Hello!"
             },
             {
                "type": "getmsg",
                "startid": 43
             }
         ]
  },
  {
     "type": "status",
     "status": 0,
     "statustext": "working on essay..."
  }
]

Sample Response
[
    {
        "type": "chat",
        "chatID": 23,
        "content":
            [
                {
                    "type": "msg",
                    "client": (client id goes here),
                    "msg": "Hi!"
                },
                {
                    "type": "msg",
                    "client": (client id goes here),
                    "msg": "How are you?"
                }
            ]
    },
    {
        "type": "status",
        "client": (client id goes here),
        "status": 1,
        "statustext": ":P"
    }
]
*/
var CHAT_URL = "chat.aspx";
var UPDATE_INTERVAL = 1000;
var chatman = null;

function Error(str) {
    window.alert(str);
}
//class ChatClient
function ChatClient(id) {
    if(arguments.length < 1)
        Error("Too few arguments for client");
    this.uid = id;
    this.name = "";
    this.status = ChatClient.OFFLINE;
    this.statusText = "";
}
//status constants
ChatClient.prototype.OFFLINE = 0;
ChatClient.prototype.AVAILABLE = 1;
ChatClient.prototype.BUSY = 2;
ChatClient.prototype.AFK = 3;

//class Chat
function Chat() {
    this.chatID = 0;
    this.messages = [];
    this.clients = [];
    this.newMessages = [];
    this.statusMessages = [];
    //add all the clients
    for (var i = 0; i < arguments.length; i++)
        this.clients.push(arguments[i]);
}
Chat.prototype.AddClient = function(client) { this.clients.push(client); };
Chat.prototype.AddMessage = function(client, msg) { this.messages.push({ "client": client, "msg": msg }); };
Chat.prototype.AddStatusMessage = function(msg) { this.statusMessages.push(msg); };
Chat.prototype.SendMessage = function(msg) { this.newMessages.push(msg); }

//class ChatManager
function ChatManager(person) {
    this.xmlhttp = CreateXmlHttpRequestObject();
    this.cache = [];
    this.chats = [];
    this.client = person;
}
ChatManager.prototype.NewChat = function(dest) {
    var chat = new Chat(this.client, dest);
    var chatID = /*"xz48fDFJ"*/this.chats.length; //TODO: Grab real chatID
    chat.chatID = chatID;
    this.chats[chatID] = chat;
    return chatID;
};
ChatManager.prototype.OnReceiveServerMessage = function() {
    // retrieve the server's response

    var response = this.xmlhttp.responseText;
    // server error?
    if (response.indexOf("ERRNO") >= 0
              || response.indexOf("error:") >= 0
              || response.length == 0)
        throw (response.length == 0 ? "Void server response." : response);
    // retrieve the JSON object correspondig to the responseText element
    var responseJSON = this.xmlhttp.responseText.parseJSON();
    // retrieve the flag that says if the chat window has been cleared 
    document.writeln( "Returned:" + (responseJSON[0].type) + ";time=" + responseJSON[0].time + "<br />");


    setTimeout("RequestMessage();", UPDATE_INTERVAL);
};

//global functions to handle ajax transfer
function HandleMessage() {
    if (chatman.xmlhttp.readyState == 4) {
        // continue only if HTTP status is "OK"
        if (chatman.xmlhttp.status == 200) {
            try {
                // process the server's response
                chatman.OnReceiveServerMessage();
            }
            catch (e) {
                // display the error message
                Error(e.toString());
            }
        }
        else {
            // display the error message
            Error(chatman.xmlhttp.statusText);
        }
    }
}
function RequestMessage() {
    if (chatman.xmlhttp)
  {
    try
    {
      // don't start another server operation if such an operation 
      //   is already in progress

        if (chatman.xmlhttp.readyState == 4 ||
          chatman.xmlhttp.readyState == 0) 
      {
            var obj = [];
            //loop through all current messages
            for (var i = 0; i < chatman.chats.length; i++) {
                var ch = chatman.chats[0];
                var cinfo = { "type": "chat", "chatID": ch.chatID, "content": [] };
                var msgbody = ch.newMessages.join("<br />");
                cinfo.content.push({ "type": "msg", "msg": msgbody });
                cinfo.content.push({ "type": "getmsg", "startid": ch.messages.length });
                obj.push(cinfo);
            }
            obj = obj.concat(chatman.cache);

            chatman.xmlhttp.open("POST", CHAT_URL, true);
            chatman.xmlhttp.setRequestHeader("Content-Type",
                                   "application/json; charset=UTF-8");
            chatman.xmlhttp.onreadystatechange = HandleMessage;
            chatman.xmlhttp.send(obj.toJSONString());
      }
      else
      {
        // we will check again for new messages 
        setTimeout("RequestMessage();", UPDATE_INTERVAL);
      }
    }
    catch (e) {
        Error(e.toString());
    }
  }
}


function CreateXmlHttpRequestObject() 
{
  // will store the reference to the XMLHttpRequest object

  var xmlHttp = null;
  // this should work for all browsers except IE6 and older

  try
  {
    // try to create XMLHttpRequest object

    xmlHttp = new XMLHttpRequest();
  }
  catch(e)
  {
    // assume IE6 or older

    var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0",
                                    "MSXML2.XMLHTTP.5.0",
                                    "MSXML2.XMLHTTP.4.0",
                                    "MSXML2.XMLHTTP.3.0",
                                    "MSXML2.XMLHTTP",
                                    "Microsoft.XMLHTTP");
    // try every prog id until one works

    for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++) 
    {
      try 
      { 
        // try to create XMLHttpRequest object

        xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
      } 
      catch (e) {}
    }
  }
  // return the created object or display an error message

  if (!xmlHttp)
    alert("Error creating the XMLHttpRequest object.");
  else 
    return xmlHttp;
}
